﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Xml;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Collections.Specialized;

namespace WorkerRole.Main
{
    class BackupScheduler
    {

        public static bool BackupSchedulerExecute(LogDataContext logContext, string inputXML)
        {
            //logContext.SaveEvent("Starting the Backup Process");

            if (inputXML.Trim().Length > 0)
            {

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(inputXML);

                try
                {
                    foreach (XmlNode node in doc.DocumentElement.SelectNodes("Database"))
                    {
                        #region Get Values from XML
                        DatabaseInfo databaseInfo = new DatabaseInfo();

                        databaseInfo.ServerName = (node.Attributes["ServerName"] != null ? node.Attributes["ServerName"].Value : string.Empty);
                        databaseInfo.DatabaseName = (node.Attributes["DatabaseName"] != null ? node.Attributes["DatabaseName"].Value : string.Empty);
                        databaseInfo.LoginId = (node.Attributes["LoginId"] != null ? node.Attributes["LoginId"].Value : string.Empty);
                        databaseInfo.Password = (node.Attributes["Password"] != null ? node.Attributes["Password"].Value : string.Empty);
                        databaseInfo.BackupFileName = (node.Attributes["BackupFileName"] != null ? node.Attributes["BackupFileName"].Value : "Backup_" + databaseInfo.DatabaseName + "_@Date_@Time_@Table.dat");
                        databaseInfo.BackupScheduledPeriod = (node.Attributes["BackupScheduledPeriod"] != null ? Convert.ToInt16(node.Attributes["BackupScheduledPeriod"].Value) :24);
                        databaseInfo.BackupScheduledTime = (node.Attributes["BackupScheduledTime"] != null ? Convert.ToDateTime(node.Attributes["BackupScheduledTime"].Value) : DateTime.Today);
                        databaseInfo.LastBackupDateTime = (node.Attributes["LastBackupDateTime"].Value.Trim().Length == 0 ? System.DateTime.Now : Convert.ToDateTime(node.Attributes["LastBackupDateTime"].Value));
                        databaseInfo.ExportFileDirectory = (node.Attributes["ExportFileDirectory"] != null ? node.Attributes["ExportFileDirectory"].Value.Replace("@Date", DateTime.Now.ToString("ddMMMMyyyy")).Replace("@Time", DateTime.Now.ToString("HHmmss")) : string.Empty);
                        databaseInfo.UseSSL = (node.Attributes["UseSSL"] != null ? Convert.ToBoolean(node.Attributes["UseSSL"].Value) : false);
                        databaseInfo.StorageAccountName = (node.Attributes["StorageAccountName"] != null ? node.Attributes["StorageAccountName"].Value : string.Empty);
                        databaseInfo.BlobContainerName = (node.Attributes["BlobContainerName"] != null ? node.Attributes["BlobContainerName"].Value : string.Empty);
                        databaseInfo.BlobDefaultEndpointsProtocol = (node.Attributes["BlobDefaultEndpointsProtocol"] != null ? node.Attributes["BlobDefaultEndpointsProtocol"].Value : string.Empty);
                        databaseInfo.StorageAccessKey = (node.Attributes["StorageAccessKey"] != null ? node.Attributes["StorageAccessKey"].Value : string.Empty);
                        #endregion

                      //  logContext.SaveEvent("Starting Process for " + databaseInfo.DatabaseName + "@" + databaseInfo.ServerName);

                        bool IsProceed = false;
                      /*
                        logContext.SaveEvent("Validation \n LastBackupDateTime : " + databaseInfo.LastBackupDateTime.ToString("dd-MMM-yyyy") + " <= " + System.DateTime.Now.ToString("dd-MMM-yyyy") +
                                                        "\n BackupScheduledHours : " + databaseInfo.BackupScheduledTime.Hour.ToString() + " == " + System.DateTime.Now.Hour.ToString() +
                                                        "\n and Minutes: " + databaseInfo.BackupScheduledTime.Minute.ToString() + " <= " + System.DateTime.Now.Minute.ToString());
                       * */
                        #region Validation
                        DateTime lastBackupTime = Convert.ToDateTime(databaseInfo.LastBackupDateTime);
                        // force to backup right now if skipped for too long...
                        if (DateTime.Now.Subtract(lastBackupTime).TotalHours >= (databaseInfo.BackupScheduledPeriod * 2))
                        {
                            IsProceed = true;
                        } else if (DateTime.Now.Subtract(lastBackupTime).TotalHours >= databaseInfo.BackupScheduledPeriod)
                        {
                            if ((databaseInfo.BackupScheduledTime.Hour == System.DateTime.Now.Hour) &&
                                (databaseInfo.BackupScheduledTime.Minute <= System.DateTime.Now.Minute))
                            {
                                IsProceed = true;
                            }

                        }

                        //IsProceed = true;

                        #endregion

                        if (IsProceed == true)
                        {
                            // save before doing, because backup takes longer than interval and it would execute backup in parallel again
                            node.Attributes["LastBackupDateTime"].Value = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm");
                            Settings.PutInputXML(logContext, doc.InnerXml);

                            logContext.SaveEvent("Backup Started for database " + databaseInfo.DatabaseName + "@" + databaseInfo.ServerName + " at " + DateTime.Now.ToString("ddMMMMyyyy HHMMSS"));
                            BackupWorker backup = new BackupWorker(logContext);
                            backup.Start(databaseInfo);
                        }
                        else
                        {
                           // logContext.SaveEvent("Validation failed for database " + databaseInfo.DatabaseName + "@" + databaseInfo.ServerName);
                        }

                    }

                    return true;
                }
                catch (Exception ex)
                {
                    logContext.SaveError(String.Format("Error Occured : {0} at {1}", ex.Message, System.DateTime.Now.ToString("dd-MMM-yyyy hh:mm")), ex.Message + "\\" + ex.StackTrace);
                }
                return false;
            }
            else
            {
                logContext.SaveError("XML File does not found", "Checking File Exist");
            }
            logContext.SaveEvent("Ending the Backup Process");
            return false;
        }



    }
}
